package com.example.service;

import com.baomidou.mybatisplus.extension.service.IService;
import com.example.domain.Lecture;
import com.example.domain.User;
import com.example.dto.LectureAddDTO;
import com.example.dto.LectureUpdateDTO;
import com.example.util.Result;

import java.util.List;
import java.util.Map;

/**
* @author HP
* @description 针对表【lecture】的数据库操作Service
* @createDate 2025-08-18 19:33:01
*/
public interface LectureService extends IService<Lecture> {

    /**
     * 添加讲座
     * @param lectureAddDTO 讲座信息
     * @return 是否添加成功
     */
    Result addLecture(LectureAddDTO lectureAddDTO);

    /**
     * 更新讲座
     * @param lectureUpdateDTO 讲座信息
     * @return 是否更新成功
     */
    Result updateLecture(LectureUpdateDTO lectureUpdateDTO);

    /**
     * 删除讲座
     * @param id 讲座ID
     * @return 是否删除成功
     */
    Result deleteLecture(Long id);

    /**
     * 根据ID查询讲座
     * @param id 讲座ID
     * @return 讲座信息
     */
    Lecture getLectureById(Long id);

    /**
     * 查询所有讲座
     * @return 讲座列表
     */
    List<Lecture> listAllLectures();

    /**
     * 获取讲座详细信息（包含图书馆ID等关联信息）
     * @param lectureId 讲座ID
     * @param userId 用户ID（可选，用于获取用户报名状态）
     * @return 讲座详细信息
     */
    com.example.vo.LectureVO getLectureWithDetails(Long lectureId, Long userId);

    /**
     * 获取所有讲座的详细信息列表
     * @param userId 用户ID（可选，用于获取用户报名状态）
     * @return 讲座详细信息列表
     */
    List<com.example.vo.LectureVO> listAllLecturesWithDetails(Long userId);

    /**
     * 用户预约讲座
     * @param userId 用户ID
     * @param lectureId 讲座ID
     * @return 是否预约成功
     */
    boolean reserveLecture(Long userId, Long lectureId);

    /**
     * 查询讲座的预约用户
     * @param lectureId 讲座ID
     * @return 用户列表
     */
    List<User> getLectureReservations(Long lectureId);

    /**
     * 查询讲座报名统计信息
     * @param lectureId 讲座ID
     * @return 统计信息
     */
    Map<String, Object> getRegistrationStatistics(Long lectureId);

    /**
     * 检查讲座是否已满员
     * @param lectureId 讲座ID
     * @return 是否满员
     */
    boolean isLectureFull(Long lectureId);

    /**
     * 获取讲座剩余名额
     * @param lectureId 讲座ID
     * @return 剩余名额数量，-1表示无限制
     */
    int getRemainingSlots(Long lectureId);

    /**
     * 用户取消报名
     * @param userId 用户ID
     * @param lectureId 讲座ID
     * @return 是否取消成功
     */
    boolean cancelRegistration(Long userId, Long lectureId);

    /**
     * 管理员取消用户报名
     * @param userId 用户ID
     * @param lectureId 讲座ID
     * @param operatorId 操作人ID
     * @param reason 取消原因
     * @return 是否取消成功
     */
    boolean adminCancelRegistration(Long userId, Long lectureId, Long operatorId, String reason);

    /**
     * 查询用户的报名记录
     * @param userId 用户ID
     * @return 报名记录列表
     */
    List<Map<String, Object>> getUserRegistrations(Long userId);

    /**
     * 检查用户是否已报名某讲座
     * @param userId 用户ID
     * @param lectureId 讲座ID
     * @return 是否已报名
     */
    boolean hasUserRegistered(Long userId, Long lectureId);

    /**
     * 获取用户在某讲座的报名状态
     * @param userId 用户ID
     * @param lectureId 讲座ID
     * @return 报名状态信息
     */
    Map<String, Object> getUserRegistrationStatus(Long userId, Long lectureId);

    // ==================== 签到管理功能 ====================

    /**
     * 用户签到
     * @param userId 用户ID
     * @param lectureId 讲座ID
     * @return 是否签到成功
     */
    boolean checkInLecture(Long userId, Long lectureId);

    /**
     * 用户通过报名记录ID签到
     * @param userId 用户ID
     * @param registrationId 报名记录ID
     * @return 是否签到成功
     */
    boolean checkInLectureByRegistrationId(Long userId, Long registrationId);

    /**
     * 管理员代替用户签到
     * @param userId 目标用户ID
     * @param lectureId 讲座ID
     * @param operatorId 操作管理员ID
     * @return 是否签到成功
     */
    boolean adminCheckInLecture(Long userId, Long lectureId, Long operatorId);

    /**
     * 批量签到
     * @param lectureId 讲座ID
     * @param userIds 用户ID列表
     * @param operatorId 操作管理员ID
     * @return 签到结果（成功数量、失败列表等）
     */
    Map<String, Object> batchCheckIn(Long lectureId, List<Long> userIds, Long operatorId);

    /**
     * 取消签到（管理员功能）
     * @param userId 用户ID
     * @param lectureId 讲座ID
     * @param operatorId 操作管理员ID
     * @param reason 取消原因
     * @return 是否取消成功
     */
    boolean cancelCheckIn(Long userId, Long lectureId, Long operatorId, String reason);

    /**
     * 查询讲座签到列表
     * @param lectureId 讲座ID
     * @return 签到用户列表
     */
    List<Map<String, Object>> getLectureCheckInList(Long lectureId);

    /**
     * 查询讲座未签到列表
     * @param lectureId 讲座ID
     * @return 未签到用户列表
     */
    List<Map<String, Object>> getLectureNotCheckInList(Long lectureId);

    /**
     * 检查用户是否可以签到
     * @param userId 用户ID
     * @param lectureId 讲座ID
     * @return 签到检查结果
     */
    Map<String, Object> checkSignInEligibility(Long userId, Long lectureId);

    Result getLecturesByRoomId(Long roomId);
}
